#include "stdafx.h"
#include "SpriteCommand.h"
#include "InputManager.h"
#include "Database.h"

SpriteCommand::SpriteCommand() :Sprite(){}

SpriteCommand::SpriteCommand(Bitmap* background, int aniId, bool type){
	this->SpriteCommand::SpriteCommand(background, &animations[aniId], type);
}
SpriteCommand::SpriteCommand(Bitmap* background, AnimationData* data, bool type) :
	Sprite(background) { setSelectedAni(data); setupContents(type, new Bitmap());
}

SpriteCommand::SpriteCommand(Bitmap* background, int aniId, Bitmap* fontFace, string txt) {
	this->SpriteCommand::SpriteCommand(background, &animations[aniId], fontFace, txt);
}
SpriteCommand::SpriteCommand(Bitmap* background, AnimationData* data, Bitmap* fontFace, string txt) {
	this->SpriteCommand::SpriteCommand(background, new Animation(data), fontFace, txt);
}
SpriteCommand::SpriteCommand(Bitmap* background, Animation* ani, Bitmap* fontFace, string txt) :
	Sprite(background) {
	initSprites();
	setupContents(false, fontFace);
	setSelectedAni(ani); setText(txt);
}

SpriteCommand::SpriteCommand(Bitmap* background, int aniId, Bitmap* img) {
	this->SpriteCommand::SpriteCommand(background, &animations[aniId], img);
}
SpriteCommand::SpriteCommand(Bitmap* background, AnimationData* data, Bitmap* img) {
	this->SpriteCommand::SpriteCommand(background, new Animation(data), img);
}
SpriteCommand::SpriteCommand(Bitmap* background, Animation* ani, Bitmap* img) :
	Sprite(background) {
	initSprites();
	setupContents(true, img);
	setSelectedAni(ani); 
}

SpriteCommand::~SpriteCommand() {
	delete textDisplay;
	delete textSprite;
}

void SpriteCommand::initSprites() {
	activeShine = activeShake = true;
	activeShineChar = '.';
	textDisplay = NULL;
	textSprite = NULL;
	selectedAniSprite = NULL;
}

void SpriteCommand::setupContents(bool type, Bitmap* bitmap) {
	removeChild(textDisplay);
	removeChild(textSprite);
	if (textDisplay != NULL) delete textDisplay;
	if (textSprite != NULL) delete textSprite;
	textDisplay = NULL; textSprite = NULL;
	if (imgCommand = type) textSprite = new Sprite(bitmap);
	else textDisplay = new TextDisplay(bitmap);
	addChild(contentSprite = (type ? textSprite : textDisplay));
	contentSprite->x = (getSpriteWidth() - contentSprite->getSpriteWidth()) / 2;
	contentSprite->y = (getSpriteHeight() - contentSprite->getSpriteHeight()) / 2;
}
void SpriteCommand::setText(string txt) {
	if (imgCommand) return; textDisplay->setText(txt);
}
string SpriteCommand::getText() { return imgCommand ? "" : textDisplay->getText(); }

void SpriteCommand::select() {
	selected = true;
	selectedAniSprite->start();
	selectedAniSprite->visible = true;
	if (activeShine)contentSprite->shine(activeShineChar, -1);
	if (activeShake)contentSprite->shake(5, 5);
}
void SpriteCommand::deselect() {
	selected = false;
	selectedAniSprite->stop();
	selectedAniSprite->visible = false;
	contentSprite->shine('T', 0);
}
void SpriteCommand::activate() {
	selectedAniSprite->play();
}
void SpriteCommand::deactivate() {
	selectedAniSprite->pause();
}
bool SpriteCommand::isSelected() { return selected; }

void SpriteCommand::setActiveShine(bool val) { activeShine = val; }
void SpriteCommand::setActiveShineChar(char c) { activeShineChar = c; }
void SpriteCommand::setActiveShake(bool val) { activeShake = val; }

bool SpriteCommand::getActiveShine() { return activeShine; }
bool SpriteCommand::getActiveShake() { return activeShake; }

void SpriteCommand::clearSelectedAni() { setSelectedAni(NULL); }
void SpriteCommand::setSelectedAni(int aniId) { setSelectedAni(&animations[aniId]); }
void SpriteCommand::setSelectedAni(AnimationData* data) { setSelectedAni(new Animation(data)); }
void SpriteCommand::setSelectedAni(Animation* ani) {
	if (selectedAniSprite != NULL) 
		removeChild(selectedAniSprite);
	selectedAniSprite = ani;
	if (ani == NULL) return;
	selectedAniSprite->setLoop(true);
	selectedAniSprite->z = -5;
	selectedAniSprite->stop();
	selectedAniSprite->visible = false;
	addChild(selectedAniSprite);
}


SpriteCommandGroup::SpriteCommandGroup(Bitmap* background, int aniId, int firstSelect) {
	this->SpriteCommandGroup::SpriteCommandGroup(background, NULL, &animations[aniId], firstSelect);
}
SpriteCommandGroup::SpriteCommandGroup(Bitmap* background, Bitmap* fontFace, int aniId, int firstSelect) {
	this->SpriteCommandGroup::SpriteCommandGroup(background, &animations[aniId], firstSelect);
}
SpriteCommandGroup::SpriteCommandGroup(Bitmap* background, AnimationData* data, int firstSelect) {
	this->SpriteCommandGroup::SpriteCommandGroup(background, NULL, data, firstSelect);
}
SpriteCommandGroup::SpriteCommandGroup(Bitmap* background, Bitmap* fontFace, AnimationData* data, int firstSelect) {
	keyCd = 0;
	selectedAniData = data;
	selectedAni = new Animation(data);
	this->background = background;
	this->fontFace = fontFace;
	this->firstSelect = firstSelect;
}

SpriteCommandGroup::~SpriteCommandGroup() { clearCommands(); }

SpriteCommand* SpriteCommandGroup::addCommand(string txt) {
	return addCommand(txt, fontFace);
}
SpriteCommand* SpriteCommandGroup::addCommand(string txt, Bitmap* fontFace) {
	if (fontFace != NULL) return addCommand(new SpriteCommand(background, selectedAniData, fontFace, txt));
	return NULL;
}
SpriteCommand* SpriteCommandGroup::addCommand(Bitmap* img) {
	return addCommand(new SpriteCommand(background, selectedAniData, img));
}
SpriteCommand* SpriteCommandGroup::addCommand(SpriteCommand* command) {
	commands.push_back(command);
	addChild(command);
	select(firstSelect);
	return command;
}
SpriteCommand* SpriteCommandGroup::getCommand(int id) { return commands[id]; }

void SpriteCommandGroup::clearCommands() {
	for (int i = 0; i < commands.size(); i++) delete commands[i];
	commands.clear(); clearChildren();
}

int SpriteCommandGroup::getCount() { return commands.size(); }

void SpriteCommandGroup::setLoop(bool l) { loop = l; }

bool SpriteCommandGroup::isActive() { return active; }

void SpriteCommandGroup::activate() { 
	active = true; commands[index]->activate();
}
void SpriteCommandGroup::deactivate() { 
	active = false; commands[index]->deactivate();
}

void SpriteCommandGroup::select(int id) {
	deselect(); index = id; indexChanged = true;
	if (commands.size() > id) commands[id]->select();
}
void SpriteCommandGroup::deselect() { deselect(index); }
void SpriteCommandGroup::deselect(int id) { if (commands.size() > id) commands[id]->deselect(); }

bool SpriteCommandGroup::isIndexChanged() {
	bool res = indexChanged; indexChanged = false; return res;
}

void SpriteCommandGroup::setActiveShine(bool val) { 
	for (int i = 0; i < commands.size(); i++)
		commands[i]->setActiveShine(val);
}
void SpriteCommandGroup::setActiveShineChar(char c) {
	for (int i = 0; i < commands.size(); i++)
		commands[i]->setActiveShineChar(c);
}
void SpriteCommandGroup::setActiveShake(bool val) {
	for (int i = 0; i < commands.size(); i++)
		commands[i]->setActiveShake(val);
}

int SpriteCommandGroup::getIndex() { return index; }

int SpriteCommandGroup::getWidth() {
	int res = 0;
	for (int i = 0; i < commands.size(); i++) {
		res = max(commands[i]->getWidth(), res);
	}
	return res;
}
int SpriteCommandGroup::getHeight() {
	if (commands.empty()) return 0;
	int k = 0;
	for (int i = 1; i < commands.size(); i++) {
		if (commands[k]->y < commands[i]->y) k = i;
	}
	return commands[k]->y + commands[k]->getHeight();
}

void SpriteCommandGroup::scrollUp() {
	int id = loop ? ((index - 1 + getCount()) % getCount()) : max(0, index - 1);
	select(id);
}
void SpriteCommandGroup::scrollDown() {
	int id = loop ? ((index + 1) % getCount()) : min(getCount()-1, index + 1);
	select(id);
}

void SpriteCommandGroup::updateOthers() {
	Sprite::updateOthers();
	updateControl();
}
void SpriteCommandGroup::updateControl() {
	if (--keyCd > 0 || !isActive()) return;
	int ud = InputManager::UD();
	if (ud == 0) return; keyCd = 5;
	ud > 0 ? scrollDown() : scrollUp();
}